package MyThread_demo.zidingyixianchengchi;

import javafx.concurrent.Worker;
import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.concurrent.TimeUnit;

/**
 * @author ChenYongHao
 * @date 2023/5/4 16:36
 * @desc
 */
// 自定义线程池
//@Slf4j
//public class ThreadPool {
//    private int coreSize;                                   // 核心线程数
//    private Long timeout;                                   // 超时时间值
//    private TimeUnit timeUnit;                              // 时间工具类
//    private HashSet<Worker> workers = new HashSet<>();      // 线程集合
//    private BlockingQueue<Runnable> taskQueue;              // 阻塞队列
//
//    public ThreadPool(int coreSize, Long timeout, TimeUnit timeUnit, int taskQueueSize) {
//        this.coreSize = coreSize;
//        this.timeout = timeout;
//        this.timeUnit = timeUnit;
//        this.taskQueue = new BlockingQueue<>(taskQueueSize);
//    }
//}


// 自定义线程池  Worker 工作线程。
@Slf4j
public class ThreadPool {
    private int coreSize;                                   // 核心线程数
    private Long timeout;                                   // 超时时间值
    private TimeUnit timeUnit;                              // 时间工具类
    private HashSet<Worker> workers = new HashSet<>();      // 线程集合
    private BlockingQueue<Runnable> taskQueue;              // 阻塞队列

    public ThreadPool(int coreSize, Long timeout, TimeUnit timeUnit, int taskQueueSize) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.taskQueue = new BlockingQueue<>(taskQueueSize);
    }

    // 工作线程
    class Worker extends Thread {
        private Runnable task;

        public Worker(Runnable task) {
            this.task = task;
        }

        @Override
        public void run() {
            // 运行任务
            while (task != null || (task = taskQueue.poll(timeout, timeUnit)) != null) {
                try {
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    task = null;
                }
            }
            // 释放线程
            synchronized (workers) {
                log.info("移除线程：{}", this);
                workers.remove(this);
            }
        }
    }

    // 执行任务
    public void execute(Runnable task) {
        // 当任务数没有超过 coreSize 时，直接交给 worker 对象执行
        // 当任务数已经超过 coreSize 时，将 task 加入阻塞队列之中
        synchronized (workers) {
            if (workers.size() < coreSize) {
                Worker worker = new Worker(task);
                log.debug("新增 worker 执行 {}", worker, task);
                workers.add(worker);
                worker.start();
            } else {
                taskQueue.put(task);
            }
        }
    }
}

